import requests from PIL import Image, ImageDraw, ImageFont, ImageOps import qrcode import serial import io def download_image(url): response = requests.get(url) response.raise_for_status() image = Image.open(io.BytesIO(response.content)) image = image.resize((320, 480)) # Resize to 320x480 if image.mode != 'RGB': image = image.convert('RGB') return image def image_to_rgb565_bytes(image): width, height = image.size rgb565_data = bytearray() # Process from bottom to top, left to right for y in reversed(range(height)): for x in range(width): r, g, b = image.getpixel((x, y)) # Convert to RGB565 r5 = (r >> 3) & 0x1F g6 = (g >> 2) & 0x3F b5 = (b >> 3) & 0x1F rgb565 = (r5 << 11) | (g6 << 5) | b5 # Big-endian bytes rgb565_data.append((rgb565 >> 8) & 0xFF) rgb565_data.append(rgb565 & 0xFF) return bytes(rgb565_data) def send_serial_data(serial_port, data): try: with serial.Serial( port=serial_port, baudrate=115200, bytesize=serial.EIGHTBITS, stopbits=serial.STOPBITS_ONE, parity=serial.PARITY_NONE, timeout=1 ) as ser: ser.write(data) except Exception as e: print(f"Serial communication error: {e}") def main(): serial_port = input("Enter serial port (e.g. COM3 or /dev/ttyUSB0): ") while True: print("\nOptions:") print("1. Welcome Screen") print("2. Draw QR Screen") print("3. Success Screen") print("4. Pending Screen") print("5. Fail Screen") print("6. Fail with Reason") print("7. Cancle Screen") print("8. Exit") choice = input("Enter your choice: ") if choice == '1': # Welcome Screen try: img = download_image("http://download.rechargegrid.in/download/general/image/jpeg/_home.jpg") data = image_to_rgb565_bytes(img) send_serial_data(serial_port, data) print("Welcome screen sent.") except Exception as e: print(f"Error: {e}") elif choice == '2': # QR Screen upi_url = input("Enter UPI URL: ") upi_id = input("Enter UPI ID: ") amount = input("Enter Amount: ") try: # Download background bg = download_image("http://download.rechargegrid.in/download/general/image/jpeg/_background.jpg") # Generate QR code qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=8, border=1, ) qr.add_data(upi_url) qr.make(fit=True) qr_img = qr.make_image(fill_color="black", back_color="white").convert('RGB') qr_img = qr_img.resize((260, 260)) # Paste QR onto background at (30,170) bg.paste(qr_img, (30, 150)) # Draw amount text draw = ImageDraw.Draw(bg) try: font = ImageFont.truetype("arialbd.ttf", 33) # Adjusted font size to 30 except IOError: font = ImageFont.load_default() text = f"₹ {amount}" text_bbox = draw.textbbox((0, 0), text, font=font) text_width = text_bbox[2] - text_bbox[0] x = (320 - text_width) // 2 # Center the text horizontally y = 130 - text_bbox[3] - 3 # Position above the QR code with 10px margin draw.text((x, y), text, fill="black", font=font) # Set text color to black # UPI ID text below QR try: small_font = ImageFont.truetype("arial.ttf", 20) # Define small font except IOError: small_font = ImageFont.load_default() text = f"UPI ID: {upi_id}" upi_text_bbox = draw.textbbox((0, 0), upi_id, font=small_font) upi_text_width = upi_text_bbox[2] - upi_text_bbox[0] upi_x = (250 - upi_text_width) // 2 # Center the UPI ID upi_y = 430 # Position below the QR code draw.text((upi_x, upi_y), text, fill="black", font=small_font) # Convert and send data = image_to_rgb565_bytes(bg) send_serial_data(serial_port, data) print("QR screen sent.") except Exception as e: print(f"Error: {e}") elif choice == '3': # Success Screen amount = input("Enter Amount: ") try: img = download_image("http://download.rechargegrid.in/download/general/image/jpeg/_success.jpg") draw = ImageDraw.Draw(img) # Load font try: font_large = ImageFont.truetype("arialbd.ttf", 34) # Large font for the main message font_small = ImageFont.truetype("arialbd.ttf", 20) # Smaller font for the "Congratulations" text except IOError: font_large = ImageFont.load_default() font_small = ImageFont.load_default() # Main payment successful message payment_text = f" ₹ {amount}" payment_bbox = draw.textbbox((0, 0), payment_text, font=font_large) payment_width = payment_bbox[2] - payment_bbox[0] payment_height = payment_bbox[3] - payment_bbox[1] x_payment = (320 - payment_width) // 2 y_payment = 250 # Set a fixed position near the top of the image draw.text((x_payment, y_payment), payment_text, fill="black", font=font_large) # Convert the image to RGB565 and send to the serial port data = image_to_rgb565_bytes(img) send_serial_data(serial_port, data) print("Success screen sent.") except Exception as e: print(f"Error: {e}") elif choice == '4': # Amazon Success with Reward amount = input("Enter Amount: ") try: # Same logic as Success Screen, different background img = download_image("http://download.rechargegrid.in/download/general/image/jpeg/_pending.jpg") draw = ImageDraw.Draw(img) # Load a font that supports Unicode characters like ₹ try: font_large = ImageFont.truetype("arialbd.ttf", 34) # Arial Bold, size 24 # Use NotoSans-Bold.ttf or any Unicode font font_small = ImageFont.truetype("arialbd.ttf", 20) # Smaller font for other text except IOError: font_large = ImageFont.load_default() # Fallback to default font font_small = ImageFont.load_default() # Set the dynamic message, now with the ₹ symbol text = f"₹ {amount}" # Calculate text size and position text_bbox = draw.textbbox((0, 0), text, font=font_large) text_width = text_bbox[2] - text_bbox[0] text_height = text_bbox[3] - text_bbox[1] x = (320 - text_width) // 2 # Horizontally center the text y = 250 # Position the text near the top of the image # Draw the bold text on the image draw.text((x, y), text, fill="black", font=font_large) # Convert image to RGB565 and send it via serial data = image_to_rgb565_bytes(img) send_serial_data(serial_port, data) print("Amazon Success with Reward screen sent.") except Exception as e: print(f"Error: {e}") elif choice == '5': # Amazon Fail without Reason try: # Same logic as Welcome Screen, different background img = download_image("http://download.rechargegrid.in/download/general/image/jpeg/_fail.jpg") data = image_to_rgb565_bytes(img) send_serial_data(serial_port, data) print("Fail without Reason screen sent.") except Exception as e: print(f"Error: {e}") elif choice == '6': # Amazon Fail with Reason reason = input("Enter Reason for Failure: ") try: # Same logic as Success Screen, but display "Payment Failed Reason" text img = download_image("http://download.rechargegrid.in/download/general/image/jpeg/_fail.jpg") draw = ImageDraw.Draw(img) try: font = ImageFont.truetype("arialbd.ttf", 24) except IOError: font = ImageFont.load_default() # Two-line text text = f"Reason: {reason}" # Compute bounding box for multiline text text_bbox = draw.multiline_textbbox((0, 0), text, font=font) text_width = text_bbox[2] - text_bbox[0] text_height = text_bbox[3] - text_bbox[1] x = (320 - text_width) // 2 y = (550 - text_height) // 2 draw.multiline_text((x, y), text, fill="black", font=font, align="center") data = image_to_rgb565_bytes(img) send_serial_data(serial_port, data) print("Fail with Reason screen sent.") except Exception as e: print(f"Error: {e}") elif choice == '7': # Amazon Fail without Reason try: # Same logic as Welcome Screen, different background img = download_image("http://download.rechargegrid.in/download/general/image/jpeg/_cancelled.jpg") data = image_to_rgb565_bytes(img) send_serial_data(serial_port, data) print("Cancle without Reason screen sent.") except Exception as e: print(f"Error: {e}") elif choice == '8': print("Exiting...") break else: print("Invalid choice. Please try again.") if __name__== "__main__": main()